#include <linux/module.h>
#include "linux/init.h"

#include "linux/fs.h"
#include "linux/kdev_t.h"
#include "linux/cdev.h"

#include "linux/uaccess.h"
static dev_t dev_num;  // 设备号
struct cdev cdev_test; // 设备结构体
struct class *class_test;

ssize_t chrdev_read(struct file *file, char __user *buff, size_t size, loff_t *off)
{
    printk(KERN_EMERG "read\n");
    return 0;
}
ssize_t chrdev_write(struct file *file, const char __user *buff, size_t size, loff_t *off)
{
    printk(KERN_EMERG "write\n");
    return 0;
}
int chrdev_open(struct inode *inode, struct file *file)
{
    printk(KERN_EMERG "open\n");
    return 0;
}

int chrdev_release(struct inode *inode, struct file *file)
{
    printk(KERN_EMERG "release\n");
    return 0;
}

struct file_operations cdev_test_ops = {
    .owner = THIS_MODULE,
    .read = chrdev_read,
    .write = chrdev_write,
    .open = chrdev_open,
    .release = chrdev_release,
};

static int __init helloworld_init(void)
{
    int ret = alloc_chrdev_region(&dev_num, 0, 1, "LYH_DRIVER");
    if (ret < 0)
    {
        printk(KERN_ERR "申请设备号失败\n");
    }
    printk(KERN_EMERG "申请设备号成功\n");
    printk(KERN_EMERG "主设备号为%d,次设备号为%d\n", MAJOR(dev_num), MINOR(dev_num));
    cdev_init(&cdev_test, &cdev_test_ops);
    ret = cdev_add(&cdev_test, dev_num, 1);
    if (ret < 0)
    {
        printk(KERN_ERR "添加设备失败\n");
    }
    printk(KERN_EMERG "添加设备成功\n");

    class_test = class_create(THIS_MODULE, "LYH_CLASS");
    device_create(class_test, NULL, dev_num, NULL, "LYH_DRIVER");


    copy_to_user()
    return 0;
}

static void __exit helloworld_exit(void)
{
    device_destroy(class_test, dev_num);
    class_destroy(class_test);
    cdev_del(&cdev_test);
    unregister_chrdev_region(dev_num, 1);
    printk(KERN_EMERG "模块卸载\r\n");
}

module_init(helloworld_init); // 注册入口函数
module_exit(helloworld_exit); // 注册出口函
MODULE_LICENSE("GPL v2");     // 同意 GPL 开源
MODULE_AUTHOR("逮就捕");      // 作者信息